package com.junlinpro.tcp;

import java.util.Date;

import com.junlinpro.entity.MessageEntity;
import com.junlinpro.utils.Constant;
import com.junlinpro.utils.CrcUtils;
import com.junlinpro.utils.DateUtil;
import com.junlinpro.utils.MessageUtil;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

import lombok.extern.slf4j.Slf4j;

/**
 * 客户端处理类
 */
@Slf4j
public class TcpNettyClientHandler extends ChannelHandlerAdapter {
	
	private boolean startFlag = true;
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	//log.info("client send data "+connectMsg);
    	//while(startFlag) {
    		MessageEntity connectMsg = buildConnectRequest();        	
        	byte[] byteMsg = MessageUtil.rtnMessageTobyte(connectMsg);
        	
        	System.out.println(CrcUtils.printHexBinary(byteMsg));

            ctx.writeAndFlush(Unpooled.copiedBuffer(byteMsg));
           // Thread.sleep(60*1000);
    	//}
    	
    }
    
   	
	@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
		log.info("--- 开始进入TcpChannelHandler ---");        
		
        ByteBuf myBuf = (ByteBuf) msg;
        log.info("myBuf.readableBytes()="+myBuf.readableBytes());
        
        MessageEntity messageEntity = MessageUtil.newBufToMessage(myBuf);
        log.info("messageEntity="+messageEntity);
        
        if (messageEntity.getCmd() == Constant.CMD_CARD_REGISTER) {//注册查询 1
        	log.info("--- 收到注册查询响应 ---");
        	byte[] byteData = messageEntity.getData(); 
        	if(byteData[0]==0x01) {//没注册
        		 //发出注册请求
        		 MessageEntity registerMsg = registerQueryRequest();
        		 byte[] byteMsg = MessageUtil.rtnMessageTobyte(registerMsg);
                 log.info("采集卡发出注册请求");
                 ctx.writeAndFlush(Unpooled.copiedBuffer(byteMsg));
        	}else if(byteData[0]==0x02) {//已经注册
        		//启动定时上报数据
        	} 
        } else if ( messageEntity.getCmd() == Constant.CMD_CARD_REGISTER_RTN ) {//注册请求11 即oxb                
        	log.info("--- 收到注册请求响应 ---");
        	byte[] byteData = messageEntity.getData(); 
        	if(byteData[0]==0x03) {//注册成功
        		//启动定时上报数据
        	}else if(byteData[0]==0x04) {//注册失败
        		/*
        		 * 由于网络问题可能无法收到服务器响应，再次发起注册请求会收到服务器注册失败的数据，建议收到这两条指令任何一条都表示注册成功。
        		 */
        		//启动定时上报数据
        	}
        } else if (messageEntity.getCmd() == Constant.CMD_CONNECT) { //创建链路18即ox12
     	   log.info("--- 收到创建链路响应 ---");
           //发送注册查询指令
     	  MessageEntity registerQueryMsg = registerQueryRequest();
     	  byte[] byteMsg = MessageUtil.rtnMessageTobyte(registerQueryMsg);
     	  log.info("采集卡发出注册查询");
     	  ctx.writeAndFlush(Unpooled.copiedBuffer(byteMsg));   
       }
        
    
	}
	
	    /**
	     *  采集卡每次重启需发送该指令，和服务器创建链接
	*
	* @return
	*/
	private MessageEntity buildConnectRequest() {
			MessageEntity sendMsg = new MessageEntity();
			
			//4A 4C 00 23 01 00 00 00 00 01 80 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5C B8 0D 0A
			//4A 4C 00 23 01 00 00 00 00 01 80 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9C 90 0D 0A
			//1 帧头2字节
			//2 长度字节数为 2 字
	     sendMsg.setAllLen(35);
			//3 协议版本字节数为 2
		 sendMsg.setVersionNum(Constant.HARDWARE_VERSION);
		 //4采集卡编号为 4 字节长
		 sendMsg.setCardId(1);
		 //5通道号为 1 字节
		 byte channelId = (byte)0x80;
		 sendMsg.setChannelId(channelId);
		 //6命令码为 1 字节  创建链路
		 byte cmd = 0x01; 
		 sendMsg.setCmd(cmd);
		 
		 //6 帧序号为每帧序号 2字节长度 发送音频数据时帧序号向上递增 其他指令写 0
		 sendMsg.setFrameId(1);
		 //7 设备类型为0 
		 byte cardType = 0x00;
		 sendMsg.setCardType(cardType);
		 //8 UTC 时间
		 int utcTimeStamp = 0;//DateUtil.transForMilliSecond(new Date());
		 sendMsg.setOccurTime(utcTimeStamp);
		 
		 //9 采集卡端数据填充为 12 字节长度 全部填写 0
		 byte[] byteData = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
		 sendMsg.setData(byteData); 
		 
		 //10 数据
		 //11 CRC 校验
		 //12 帧尾        
		 return sendMsg;
	}
    
    /**
     * 1 模拟采集卡发出注册查询报文
     */
    private MessageEntity registerQueryRequest() {
    	MessageEntity sendMsg = new MessageEntity();
    	//1 帧头2字节
    	//2 长度字节数为 2 字
    	sendMsg.setAllLen(35);
    	//3 协议版本字节数为 2
    	sendMsg.setVersionNum(Constant.HARDWARE_VERSION);
        //4采集卡编号为 4 字节长
        sendMsg.setCardId(89);
        //5通道号为 1 字节
        byte channelId = 0x00;
        sendMsg.setChannelId(channelId);
        //6命令码为 1 字节  注册查询
        byte cmd = 0x01; 
        sendMsg.setCmd(cmd);
        
        //6 帧序号为每帧序号 2字节长度 发送音频数据时帧序号向上递增 其他指令写 0
        sendMsg.setFrameId(0);
        //7 设备类型为0 
        byte cardType = 0x00;
        sendMsg.setCardType(cardType);
        //8 UTC 时间
        int utcTimeStamp = 0;//DateUtil.transForMilliSecond(new Date());
        sendMsg.setOccurTime(utcTimeStamp);
        
        //9 采集卡端数据填充为 12 字节长度 全部填写 0
        byte[] byteData = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
        sendMsg.setData(byteData); 
        
        //10 数据
        //11 CRC 校验
        //12 帧尾        
        return sendMsg;
}
    
    /**
     * 模拟采集卡发出注册请求报文
     */
    private MessageEntity registerRequest() {
    	MessageEntity sendMsg = new MessageEntity();
    	//1 帧头2字节
    	//2 长度字节数为 2 字
    	sendMsg.setAllLen(35);
    	//3 协议版本字节数为 2
        sendMsg.setVersionNum(Constant.HARDWARE_VERSION);
        //4采集卡编号为 4 字节长
        sendMsg.setCardId(89);
        //5通道号为 1 字节
        byte channelId = 0x00;
        sendMsg.setChannelId(channelId);
        //6命令码为 1 字节  注册请求
        byte cmd = 0x0B; 
        sendMsg.setCmd(cmd);
        
        //6 帧序号为每帧序号 2字节长度 发送音频数据时帧序号向上递增 其他指令写 0
        sendMsg.setFrameId(0);
        //7 设备类型为0 
        byte cardType = 0x00;
        sendMsg.setCardType(cardType);
        //8 UTC 时间
        int utcTimeStamp = DateUtil.transForMilliSecond(new Date());
        sendMsg.setOccurTime(utcTimeStamp);
        
        //9 采集卡端数据填充为 12 字节长度 全部填写 0
        byte[] byteData = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
        sendMsg.setData(byteData); 
        
        //10 数据
        //11 CRC 校验
        //12 帧尾        
        return sendMsg;
    }
    
    private MessageEntity HeartBeatRequest() {
    	MessageEntity sendMsg = new MessageEntity();
    	//1 帧头2字节
    	//2 长度字节数为 2 字
    	sendMsg.setAllLen(35);
    	//3 协议版本字节数为 2
    	sendMsg.setVersionNum(Constant.HARDWARE_VERSION);
        //4采集卡编号为 4 字节长
        sendMsg.setCardId(89);
        //5通道号为 1 字节
        byte channelId = 0x00;
        sendMsg.setChannelId(channelId);
        //6命令码为 1 字节  心跳
        byte cmd = 0x05; 
        sendMsg.setCmd(cmd);
        
        //6 帧序号为每帧序号 2字节长度 发送音频数据时帧序号向上递增 其他指令写 0
        sendMsg.setFrameId(0);
        //7 设备类型为0 
        byte cardType = 0x00;
        sendMsg.setCardType(cardType);
        //8 UTC 时间
        int utcTimeStamp = DateUtil.transForMilliSecond(new Date());
        sendMsg.setOccurTime(utcTimeStamp);
        
        //9 采集卡端数据填充为 12 字节长度 全部填写 0
        byte[] byteData = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
        sendMsg.setData(byteData); 
        
        //10 数据
        //11 CRC 校验
        //12 帧尾        
        return sendMsg;
}


    /**
             * 在处理过程中引发异常时被调用
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("[Client] netty client request error: {}", cause.getMessage());
    	ctx.close();
    }



}